package com.heima.review.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.common.constants.message.HotArticleConstants;
import com.heima.common.enums.AppHttpCodeEnum;
import com.heima.common.exception.LeadException;
import com.heima.common.threadlocal.UserThreadLocalUtils;
import com.heima.common.util.JsonUtils;
import com.heima.feign.ApArticleFeignClient;
import com.heima.model.article.dtos.ArticleBehaviorMsg;
import com.heima.model.article.dtos.ArticleDto;
import com.heima.model.comment.dtos.CommentPageQueryDTO;
import com.heima.model.comment.dtos.CommentSaveDto;
import com.heima.model.review.CommentRepaySaveDto;
import com.heima.model.review.dtos.ReviewPageDTO;
import com.heima.review.entity.AdComment;
import com.heima.review.entity.AdCommentLike;
import com.heima.review.entity.vo.CommentListVo;
import com.heima.review.mapper.AdCommentMapper;
import com.heima.review.service.AdCommentLikeService;
import com.heima.review.service.AdCommentService;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author HM
 * @since 2023-04-10
 */
@Service
public class AdCommentServiceImpl extends ServiceImpl<AdCommentMapper, AdComment> implements AdCommentService {
    @Autowired
    private ApArticleFeignClient articleFeignClient;
    @Autowired
    private AdCommentLikeService commentLikeService;
    @Autowired
    private KafkaProducer kafkaProducer;

    @Override
    public void delComment(Long commentId) {
        delete(commentId);
    }

    @Override
    public void delCommentRepay(Long replyId) {
        delete(replyId);
    }

    /**
     * 文章查询列表
     *
     * @param dto
     * @return
     */
    @Override
    public List<CommentListVo> load(ReviewPageDTO dto) {
        LambdaQueryWrapper<AdComment> queryWrapper = new LambdaQueryWrapper<>();
        if (dto.getArticleId() == null && dto.getArticleId() <= 0) {
            throw new LeadException(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        queryWrapper.eq(AdComment::getArticleId, dto.getArticleId());
        queryWrapper.lt(dto.getMinDate() != null, AdComment::getCreatedTime, dto.getMinDate());
        queryWrapper.orderByDesc(AdComment::getCreatedTime);
        Page<AdComment> page = new Page<>(1, dto.getSize());
        page(page, queryWrapper);
        List<CommentListVo> list = page.getRecords().stream().map(adComment -> {
            ArticleDto articleDto = articleFeignClient.findById(adComment.getArticleId());
            CommentListVo vo = CommentListVo.builder().id(adComment.getId())
                    .authorId(articleDto.getAuthorId()).authorName(articleDto.getAuthorName())
                    .channelId(articleDto.getChannelId()).content(adComment.getContent())
                    .reply(adComment.getReply()).likes(adComment.getLikes()).createTime(adComment.getCreatedTime()).build();
            //当前用户点赞
            Integer userId = UserThreadLocalUtils.getUserId();
            LambdaQueryWrapper<AdCommentLike> queryWrapperLike = new LambdaQueryWrapper<>();
            queryWrapperLike.eq(AdCommentLike::getUserId, userId);
            queryWrapperLike.eq(AdCommentLike::getArticleId, dto.getArticleId());
            AdCommentLike commentLike = commentLikeService.getOne(queryWrapperLike);
            if (commentLike != null && commentLike.getCommentId() == adComment.getId()) {
                vo.setOperation(0);
            }
            return vo;
        }).collect(Collectors.toList());
        return list;
    }

    /**
     * 发布回复
     *
     * @param dto
     * @return
     */
    @Override
    public void saveCommentRepay(CommentRepaySaveDto dto) {
        if (StringUtils.isEmpty(dto.getCommentId())) {
            throw new LeadException(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        //查询
        LambdaQueryWrapper<AdComment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AdComment::getId, dto.getCommentId());
        AdComment adCommentDB = this.getOne(queryWrapper);
        if (adCommentDB == null) {
            throw new LeadException(AppHttpCodeEnum.NO_OPERATOR_AUTH);
        }
        //保存回复
        AdComment adComment = new AdComment();
        adComment.setUserId(UserThreadLocalUtils.getUserId());
        adComment.setType(1);//1是回复
        adComment.setContent(dto.getContent());
        adComment.setIsdelete(0);//未删除
        adComment.setCommentId(Long.valueOf(dto.getCommentId()));
        this.save(adComment);

        //更新评论回复数量
        adCommentDB.setReply(adCommentDB.getReply() + 1);
        this.updateById(adCommentDB);
    }

    @Override
    public void delCommentByArtilceId(Long articleId) {
        QueryWrapper<AdComment> queryWrapper=new QueryWrapper<>();
        queryWrapper.lambda().eq(AdComment::getArticleId,articleId);
        queryWrapper.lambda().eq(AdComment::getIsdelete,1);
        this.update(queryWrapper);
    }

    /**
     * 发布评论
     *
     * @param dto
     * @return
     */
    @Override
    public void saveComment(CommentSaveDto dto) {
        if (Objects.isNull(dto)) {
            throw new LeadException(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        //根据文章id，feign调用查询文章
        ArticleDto article = articleFeignClient.findById(dto.getArticleId());

        if (article==null){
            throw new LeadException(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        //判断当前文章是否可以评论
        if (article.getIsComment()==false){
            throw new LeadException(AppHttpCodeEnum.NO_OPERATOR_AUTH);
        }

        //封装数据
        AdComment adComment = new AdComment();
        adComment.setArticleId(dto.getArticleId());
        adComment.setCreatedTime(new Date());
        adComment.setUserId(UserThreadLocalUtils.getUserId());
        adComment.setContent(dto.getContent());
        adComment.setType(0);//0是评论
        adComment.setReply(0);//回复数
        adComment.setLikes(0);//点赞数
        adComment.setIsdelete(0);//未删除
        this.save(adComment);

        //发送kafka更新分数
        sendKafka(dto);
    }

    public void sendKafka(CommentSaveDto dto) {
        ArticleBehaviorMsg msg = new ArticleBehaviorMsg();
        msg.setArticleId(dto.getArticleId());
        //评论+1
        msg.setNum(1);
        msg.setType(ArticleBehaviorMsg.ArticleBehaviorType.COMMENT);
        ProducerRecord<String, String> record1 = new ProducerRecord<String, String>(HotArticleConstants.HOT_ARTICLE_SCORE_STREAM_TOPIC, JsonUtils.toString(msg));
        kafkaProducer.send(record1);
        System.out.println("发送数据" + JsonUtils.toString(msg));
    }

    /**
     * 通用逻辑删除
     *
     * @param id
     */
    public void delete(Long id) {
        AdComment adComment = new AdComment();
        adComment.setCommentId(id);
        adComment.setIsdelete(1);
        this.updateById(adComment);
    }

    /**
     * 作者回复评论
     *
     * @param dto
     */
    @Override
    public void commentRepay(CommentRepaySaveDto dto) {
        //获取评论id
//        Long id = comment.getCommentId();
//        //根据评论id查询评论
//        AdComment byId = this.getById(id);
//        if (byId == null) {
//            throw new LeadException(AppHttpCodeEnum.DATA_NOT_EXIST);
//        }
//        //设置类型 0：评论 1：回复
//        byId.setType(1);
//        byId.setCreatedTime(new Date());
//        byId.setContent(comment.getContent());
//        //设置关联的回复id
//        byId.setCommentId(id);


        saveCommentRepay(dto);
    }

    /**
     * 评论和回复查询所有
     *
     * @param dto
     * @return
     */
    @Override
    public List<AdComment> getPage(CommentPageQueryDTO dto) {
        LambdaQueryWrapper<AdComment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AdComment::getArticleId, dto.getArticleId());
        Page<AdComment> ipage = new Page<>(dto.getPage(), dto.getSize());
        Page<AdComment> page = this.page(ipage, queryWrapper);
        return page.getRecords();
    }
}
